// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License.  You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//
// Author: Florian Zaruba, ETH Zurich
// Date: 16.05.2017
// Description: Instruction Tracer Defines

`ifndef VERILATOR
package instr_tracer_pkg;

  parameter INSTR_NOP = 32'h00_00_00_13;

  parameter INSTR_LUI = {25'b?, riscv::OpcodeLui};
  parameter INSTR_AUIPC = {25'b?, riscv::OpcodeAuipc};
  parameter INSTR_JAL = {25'b?, riscv::OpcodeJal};
  parameter INSTR_JALR = {17'b?, 3'b000, 5'b?, riscv::OpcodeJalr};
  // BRANCH
  parameter INSTR_BEQZ = {7'b?, 5'b0, 5'b?, 3'b000, 5'b?, riscv::OpcodeBranch};
  parameter INSTR_BEQ = {7'b?, 5'b?, 5'b?, 3'b000, 5'b?, riscv::OpcodeBranch};
  parameter INSTR_BNEZ = {7'b?, 5'b0, 5'b?, 3'b001, 5'b?, riscv::OpcodeBranch};
  parameter INSTR_BNE = {7'b?, 5'b?, 5'b?, 3'b001, 5'b?, riscv::OpcodeBranch};
  parameter INSTR_BLTZ = {7'b?, 5'b0, 5'b?, 3'b100, 5'b?, riscv::OpcodeBranch};
  parameter INSTR_BLT = {7'b?, 5'b?, 5'b?, 3'b100, 5'b?, riscv::OpcodeBranch};
  parameter INSTR_BGEZ = {7'b?, 5'b0, 5'b?, 3'b101, 5'b?, riscv::OpcodeBranch};
  parameter INSTR_BGE = {7'b?, 5'b?, 5'b?, 3'b101, 5'b?, riscv::OpcodeBranch};
  parameter INSTR_BLTU = {7'b?, 5'b?, 5'b?, 3'b110, 5'b?, riscv::OpcodeBranch};
  parameter INSTR_BGEU = {7'b?, 5'b?, 5'b?, 3'b111, 5'b?, riscv::OpcodeBranch};

  // OP-IMM
  parameter INSTR_LI = {12'b?, 5'b0, 3'b000, 5'b?, riscv::OpcodeOpImm};
  parameter INSTR_ADDI = {17'b?, 3'b000, 5'b?, riscv::OpcodeOpImm};
  parameter INSTR_SLTI = {17'b?, 3'b010, 5'b?, riscv::OpcodeOpImm};
  parameter INSTR_SLTIU = {17'b?, 3'b011, 5'b?, riscv::OpcodeOpImm};
  parameter INSTR_XORI = {17'b?, 3'b100, 5'b?, riscv::OpcodeOpImm};
  parameter INSTR_ORI = {17'b?, 3'b110, 5'b?, riscv::OpcodeOpImm};
  parameter INSTR_ANDI = {17'b?, 3'b111, 5'b?, riscv::OpcodeOpImm};
  parameter INSTR_SLLI = {6'b000000, 11'b?, 3'b001, 5'b?, riscv::OpcodeOpImm};
  parameter INSTR_SRLI = {6'b000000, 11'b?, 3'b101, 5'b?, riscv::OpcodeOpImm};
  parameter INSTR_SRAI = {6'b010000, 11'b?, 3'b101, 5'b?, riscv::OpcodeOpImm};

  // OP-IMM-32
  parameter INSTR_ADDIW = {17'b?, 3'b000, 5'b?, riscv::OpcodeOpImm32};
  parameter INSTR_SLLIW = {7'b0000000, 10'b?, 3'b001, 5'b?, riscv::OpcodeOpImm32};
  parameter INSTR_SRLIW = {7'b0000000, 10'b?, 3'b101, 5'b?, riscv::OpcodeOpImm32};
  parameter INSTR_SRAIW = {7'b0100000, 10'b?, 3'b101, 5'b?, riscv::OpcodeOpImm32};

  // OP
  parameter INSTR_ADD = {7'b0000000, 10'b?, 3'b000, 5'b?, riscv::OpcodeOp};
  parameter INSTR_SUB = {7'b0100000, 10'b?, 3'b000, 5'b?, riscv::OpcodeOp};
  parameter INSTR_SLL = {7'b0000000, 10'b?, 3'b001, 5'b?, riscv::OpcodeOp};
  parameter INSTR_SLT = {7'b0000000, 10'b?, 3'b010, 5'b?, riscv::OpcodeOp};
  parameter INSTR_SLTU = {7'b0000000, 10'b?, 3'b011, 5'b?, riscv::OpcodeOp};
  parameter INSTR_XOR = {7'b0000000, 10'b?, 3'b100, 5'b?, riscv::OpcodeOp};
  parameter INSTR_SRL = {7'b0000000, 10'b?, 3'b101, 5'b?, riscv::OpcodeOp};
  parameter INSTR_SRA = {7'b0100000, 10'b?, 3'b101, 5'b?, riscv::OpcodeOp};
  parameter INSTR_OR = {7'b0000000, 10'b?, 3'b110, 5'b?, riscv::OpcodeOp};
  parameter INSTR_AND = {7'b0000000, 10'b?, 3'b111, 5'b?, riscv::OpcodeOp};
  parameter INSTR_MUL = {7'b0000001, 10'b?, 3'b???, 5'b?, riscv::OpcodeOp};

  // OP32
  parameter INSTR_ADDW = {7'b0000000, 10'b?, 3'b000, 5'b?, riscv::OpcodeOp32};
  parameter INSTR_SUBW = {7'b0100000, 10'b?, 3'b000, 5'b?, riscv::OpcodeOp32};
  parameter INSTR_SLLW = {7'b0000000, 10'b?, 3'b001, 5'b?, riscv::OpcodeOp32};
  parameter INSTR_SRLW = {7'b0000000, 10'b?, 3'b101, 5'b?, riscv::OpcodeOp32};
  parameter INSTR_SRAW = {7'b0100000, 10'b?, 3'b101, 5'b?, riscv::OpcodeOp32};
  parameter INSTR_MULW = {7'b0000001, 10'b?, 3'b???, 5'b?, riscv::OpcodeOp32};

  // MISC-MEM
  parameter INSTR_FENCE = {4'b0, 8'b?, 13'b0, riscv::OpcodeMiscMem};
  parameter INSTR_FENCEI = {17'b0, 3'b001, 5'b0, riscv::OpcodeMiscMem};

  // SYSTEM
  parameter INSTR_CSRW = {12'b?, 5'b?, 3'b001, 5'b0, riscv::OpcodeSystem};
  parameter INSTR_CSRRW = {12'b?, 5'b?, 3'b001, 5'b?, riscv::OpcodeSystem};
  parameter INSTR_CSRR = {12'b?, 5'b0, 3'b010, 5'b?, riscv::OpcodeSystem};
  parameter INSTR_CSRRS = {12'b?, 5'b?, 3'b010, 5'b?, riscv::OpcodeSystem};
  parameter INSTR_CSRS = {12'b?, 5'b?, 3'b010, 5'b0, riscv::OpcodeSystem};
  parameter INSTR_CSRRC = {12'b?, 5'b?, 3'b011, 5'b?, riscv::OpcodeSystem};
  parameter INSTR_CSRC = {12'b?, 5'b?, 3'b011, 5'b0, riscv::OpcodeSystem};

  parameter INSTR_CSRWI = {17'b?, 3'b101, 5'b0, riscv::OpcodeSystem};
  parameter INSTR_CSRRWI = {17'b?, 3'b101, 5'b?, riscv::OpcodeSystem};
  parameter INSTR_CSRSI = {17'b?, 3'b110, 5'b0, riscv::OpcodeSystem};
  parameter INSTR_CSRRSI = {17'b?, 3'b110, 5'b?, riscv::OpcodeSystem};
  parameter INSTR_CSRCI = {17'b?, 3'b111, 5'b0, riscv::OpcodeSystem};
  parameter INSTR_CSRRCI = {17'b?, 3'b111, 5'b?, riscv::OpcodeSystem};

  parameter INSTR_ECALL = {12'b000000000000, 13'b0, riscv::OpcodeSystem};
  parameter INSTR_EBREAK = {12'b000000000001, 13'b0, riscv::OpcodeSystem};
  parameter INSTR_MRET = {12'b001100000010, 13'b0, riscv::OpcodeSystem};
  parameter INSTR_SRET = {12'b000100000010, 13'b0, riscv::OpcodeSystem};
  parameter INSTR_DRET = {12'b011110110010, 13'b0, riscv::OpcodeSystem};
  parameter INSTR_WFI = {12'b000100000101, 13'b0, riscv::OpcodeSystem};
  parameter INSTR_SFENCE = {12'b0001001?????, 13'b?, riscv::OpcodeSystem};

  // RV32M
  parameter INSTR_PMUL = {7'b0000001, 10'b?, 3'b000, 5'b?, riscv::OpcodeOp};
  parameter INSTR_DIV = {7'b0000001, 10'b?, 3'b100, 5'b?, riscv::OpcodeOp};
  parameter INSTR_DIVU = {7'b0000001, 10'b?, 3'b101, 5'b?, riscv::OpcodeOp};
  parameter INSTR_REM = {7'b0000001, 10'b?, 3'b110, 5'b?, riscv::OpcodeOp};
  parameter INSTR_REMU = {7'b0000001, 10'b?, 3'b111, 5'b?, riscv::OpcodeOp};

  // RVFD
  parameter INSTR_FMADD = {5'b?, 2'b?, 5'b?, 5'b?, 3'b?, 5'b?, riscv::OpcodeMadd};
  parameter INSTR_FMSUB = {5'b?, 2'b?, 5'b?, 5'b?, 3'b?, 5'b?, riscv::OpcodeMsub};
  parameter INSTR_FNSMSUB = {5'b?, 2'b?, 5'b?, 5'b?, 3'b?, 5'b?, riscv::OpcodeNmsub};
  parameter INSTR_FNMADD = {5'b?, 2'b?, 5'b?, 5'b?, 3'b?, 5'b?, riscv::OpcodeNmadd};

  parameter INSTR_FADD = {5'b00000, 2'b?, 5'b?, 5'b?, 3'b?, 5'b?, riscv::OpcodeOpFp};
  parameter INSTR_FSUB = {5'b00001, 2'b?, 5'b?, 5'b?, 3'b?, 5'b?, riscv::OpcodeOpFp};
  parameter INSTR_FMUL = {5'b00010, 2'b?, 5'b?, 5'b?, 3'b?, 5'b?, riscv::OpcodeOpFp};
  parameter INSTR_FDIV = {5'b00011, 2'b?, 5'b?, 5'b?, 3'b?, 5'b?, riscv::OpcodeOpFp};
  parameter INSTR_FSQRT = {5'b01011, 2'b?, 5'b0, 5'b?, 3'b?, 5'b?, riscv::OpcodeOpFp};
  parameter INSTR_FSGNJ = {5'b00100, 2'b?, 5'b?, 5'b?, 3'b000, 5'b?, riscv::OpcodeOpFp};
  parameter INSTR_FSGNJN = {5'b00100, 2'b?, 5'b?, 5'b?, 3'b001, 5'b?, riscv::OpcodeOpFp};
  parameter INSTR_FSGNJX = {5'b00100, 2'b?, 5'b?, 5'b?, 3'b010, 5'b?, riscv::OpcodeOpFp};
  parameter INSTR_FMIN = {5'b00101, 2'b?, 5'b?, 5'b?, 3'b000, 5'b?, riscv::OpcodeOpFp};
  parameter INSTR_FMAX = {5'b00101, 2'b?, 5'b?, 5'b?, 3'b001, 5'b?, riscv::OpcodeOpFp};
  parameter INSTR_FLE = {5'b10100, 2'b?, 5'b?, 5'b?, 3'b000, 5'b?, riscv::OpcodeOpFp};
  parameter INSTR_FLT = {5'b10100, 2'b?, 5'b?, 5'b?, 3'b001, 5'b?, riscv::OpcodeOpFp};
  parameter INSTR_FEQ = {5'b10100, 2'b?, 5'b?, 5'b?, 3'b010, 5'b?, riscv::OpcodeOpFp};

  parameter INSTR_FCVT_F2F = {5'b01000, 2'b?, 5'b000??, 5'b?, 3'b?, 5'b?, riscv::OpcodeOpFp};
  parameter INSTR_FMV_F2X = {5'b11100, 2'b?, 5'b0, 5'b?, 3'b000, 5'b?, riscv::OpcodeOpFp};
  parameter INSTR_FCLASS = {5'b11100, 2'b?, 5'b0, 5'b?, 3'b001, 5'b?, riscv::OpcodeOpFp};
  parameter INSTR_FMV_X2F = {5'b11110, 2'b?, 5'b0, 5'b?, 3'b000, 5'b?, riscv::OpcodeOpFp};
  parameter INSTR_FCVT_F2I = {5'b11000, 2'b?, 5'b000??, 5'b?, 3'b?, 5'b?, riscv::OpcodeOpFp};
  parameter INSTR_FCVT_I2F = {5'b11010, 2'b?, 5'b000??, 5'b?, 3'b?, 5'b?, riscv::OpcodeOpFp};

  // A
  parameter INSTR_AMO = {25'b?, riscv::OpcodeAmo};

  // Load/Stores
  parameter [31:0] LB = 32'b?????????????????000?????0000011;
  parameter [31:0] LH = 32'b?????????????????001?????0000011;
  parameter [31:0] LW = 32'b?????????????????010?????0000011;
  parameter [31:0] LD = 32'b?????????????????011?????0000011;
  parameter [31:0] LBU = 32'b?????????????????100?????0000011;
  parameter [31:0] LHU = 32'b?????????????????101?????0000011;
  parameter [31:0] LWU = 32'b?????????????????110?????0000011;
  parameter [31:0] FLW = 32'b?????????????????010?????0000111;
  parameter [31:0] FLD = 32'b?????????????????011?????0000111;
  parameter [31:0] FLQ = 32'b?????????????????100?????0000111;
  parameter [31:0] SB = 32'b?????????????????000?????0100011;
  parameter [31:0] SH = 32'b?????????????????001?????0100011;
  parameter [31:0] SW = 32'b?????????????????010?????0100011;
  parameter [31:0] SD = 32'b?????????????????011?????0100011;
  parameter [31:0] FSW = 32'b?????????????????010?????0100111;
  parameter [31:0] FSD = 32'b?????????????????011?????0100111;
  parameter [31:0] FSQ = 32'b?????????????????100?????0100111;
  parameter [31:0] C_ADDI4SPN = 32'b????????????????000???????????00;
  parameter [31:0] C_FLD = 32'b????????????????001???????????00;
  parameter [31:0] C_LW = 32'b????????????????010???????????00;
  parameter [31:0] C_FLW = 32'b????????????????011???????????00;
  parameter [31:0] C_FSD = 32'b????????????????101???????????00;
  parameter [31:0] C_SW = 32'b????????????????110???????????00;
  parameter [31:0] C_FSW = 32'b????????????????111???????????00;
  parameter [31:0] C_ADDI = 32'b????????????????000???????????01;
  parameter [31:0] C_JAL = 32'b????????????????001???????????01;
  parameter [31:0] C_LI = 32'b????????????????010???????????01;
  parameter [31:0] C_LUI = 32'b????????????????011???????????01;
  parameter [31:0] C_SRLI = 32'b????????????????100?00????????01;
  parameter [31:0] C_SRAI = 32'b????????????????100?01????????01;
  parameter [31:0] C_ANDI = 32'b????????????????100?10????????01;
  parameter [31:0] C_SUB = 32'b????????????????100011???00???01;
  parameter [31:0] C_XOR = 32'b????????????????100011???01???01;
  parameter [31:0] C_OR = 32'b????????????????100011???10???01;
  parameter [31:0] C_AND = 32'b????????????????100011???11???01;
  parameter [31:0] C_SUBW = 32'b????????????????100111???00???01;
  parameter [31:0] C_ADDW = 32'b????????????????100111???01???01;
  parameter [31:0] C_J = 32'b????????????????101???????????01;
  parameter [31:0] C_BEQZ = 32'b????????????????110???????????01;
  parameter [31:0] C_BNEZ = 32'b????????????????111???????????01;
  parameter [31:0] C_SLLI = 32'b????????????????000???????????10;
  parameter [31:0] C_FLDSP = 32'b????????????????001???????????10;
  parameter [31:0] C_LWSP = 32'b????????????????010???????????10;
  parameter [31:0] C_FLWSP = 32'b????????????????011???????????10;
  parameter [31:0] C_MV = 32'b????????????????1000??????????10;
  parameter [31:0] C_ADD = 32'b????????????????1001??????????10;
  parameter [31:0] C_FSDSP = 32'b????????????????101???????????10;
  parameter [31:0] C_SWSP = 32'b????????????????110???????????10;
  parameter [31:0] C_FSWSP = 32'b????????????????111???????????10;
  parameter [31:0] C_NOP = 32'b????????????????0000000000000001;
  parameter [31:0] C_ADDI16SP = 32'b????????????????011?00010?????01;
  parameter [31:0] C_JR = 32'b????????????????1000?????0000010;
  parameter [31:0] C_JALR = 32'b????????????????1001?????0000010;
  parameter [31:0] C_EBREAK = 32'b????????????????1001000000000010;
  parameter [31:0] C_LD = 32'b????????????????011???????????00;
  parameter [31:0] C_SD = 32'b????????????????111???????????00;
  parameter [31:0] C_ADDIW = 32'b????????????????001???????????01;
  parameter [31:0] C_LDSP = 32'b????????????????011???????????10;
  parameter [31:0] C_SDSP = 32'b????????????????111???????????10;

endpackage
`endif
